package qc.common.core.enums.qms;

import com.baomidou.mybatisplus.annotation.EnumValue;
import lombok.AllArgsConstructor;
import lombok.Getter;

/**
 * QMS数据质量枚举
 *
 * @author QuCheng Tech
 * @since 2025/8/14
 */
@Getter
@AllArgsConstructor
public enum QmsPointDataQualityEnum {
    /**
     * 数据质量默认：NORMAL(8, "正常数据")
     * 通过原始采集计算或根据其点号统计出的数据默认为有效数据
     */

    /**
     * 关于不同质量的数据是否参与系统点号数据的计算、预警和转发
     * 结论：所有质量的数据均需要参与系统点号数据的计算、预警和转发
     * 原因：有可能出现原来数据质量标记为有效数据（人工、或正常）后经过人工或系统处理标记为无效数据（删除、错误等）需要按照操作后的数据质量再次进行点号数据的计算、预警和转发
     * 具体说明：如删除一段时间数据后需要对关联点号的一段时间数据再次进行计算、数据标记为错误原来产生了预警的需要进行取消、数据删除或标记错误后转发数据是否要更新由对应的转发处理进行判断（需要有消息触发）
     */

    /**
     * 人工能对点号数据进行的操作有：1-设置为错误数据、2-设置为有效数据、3-人工录入数据、4-人工删除数据
     * 1-设置为错误数据：可以对数据质量≥测试数据的进行操作
     * 2-设置为有效数据：修改数据质量标记为人工数据，可以对（除已经是人工数据外）所有质量标记的进行操作
     * 3-人工录入数据：不存在的数据新增后质量标记为人工数据，存在的数据（不为人工数据）设置质量标记为人工数据
     * 4-人工删除数据：可以对（除已删除外）所有质量标记进行操作，设置质量标记为已删除
     */

    /**
     * 不存在该质量标记，为0表示没有指定质量标记；实际系统中默认的数据质量标记只能是正常数据或人工数据
     */
    UN_DEFINE(0, "未定义"),
    /**
     * 人工操作，将指定的时间数据进行删除
     */
    DELETE(1, "已删除"),
    /**
     * 人工操作，将指定的时间数据标记为错误数据
     */
    ERROR(2, "错误数据"),
    /**
     * 系统自动生成，根据站点的检修记录时间段将指定的时间段内数据标记为测试数据；测试、调试、检修时测试数据
     */
    TEST(3, "测试数据"),
    /**
     * 2025-9-25，不单独设计演示数据
     * 虑到演示数据的用途时仅针对预警，可以在数据预警模块中再设计模拟预警触发（用于区分开是系统实际数据预警还是演习数据预警）
     * DEMO(4,"演示数据"),//系统自动生成，在系统工作模式设置为“演习模式”或通过演习数据录入或修改数据
     */
    /**
     * 2025-9-26，可疑数据当做错误数据
     * 系统自动生成，在点号数据保存时自动根据设置的点号数据的范围判断是可以数据还是正常数据；可疑数据由人工进行判定复核处理，在没有人工判定前均当做错误数据；
     * 另外可以通过定时的数据检查（根据配置的规则）对数据进行自动标记
     * 2025-10-23，考虑后调整为：
     * 通过点号或监测要素中的数据值有效范围判定的，如果进行了数据值修订则将数据质量设置为修订数据，如果没有进行数据值修订则将数据质量设置为可疑数据
     * 通过数据值告警规则进行判定的，如果进行了防误处理（修订了数据值）则将数据质量设置为正常数据，如果没有进行数据值修订则保持数据质量不变
     */
    QUESTION(5, "可疑数据"),
    /**
     * 系统自动生成，在定时数值计算后对计算的各目标时间点是否有数据值进行判断，如果没有数据值根据插补设置进行自动插补数据
     */
    FILLING(6, "插补数据"),
    /**
     * 2025-9-11，不单独设计插值数据，统一使用插补数据
     * 插补数据和插值数据均为系统计算来的数据，区别是是否超过设置的限定时间；插补数据不参与系统的预警，参与系统中的计算和转发
     * 不区分插补数据是否作为有效数据；在插补数据设置中配置插补的最长时间，超过时间就不插补数据，所有插补数据均作为有效数据
     * 是否有插值数据？如果是通过计算应该是由系统计算得到的结果数据，质量为有效数据或可疑数据；
     * INTERPOLATION(7, "插值数据"),//系统计算中设置的线性或非线性插值数据；插值数据是满足质量要求的数据；参与系统中的计算、预警和转发
     */
    /**
     * 系统自动修订数据；数据值超出点号或监测要素的有效值范围时自动修正的数据，或者数据值触发告警防误处理时自动修正的数据
     * 2025-10-23，考虑后增加修订数据
     */
    AMEND(7, "修订数据"),
    /**
     * 根据原始采集计算得到的数据、根据其他点号数据计算/统计得到的数据
     */
    NORMAL(8, "正常数据"),
    /**
     * 人工录入或人工修改的数据，人工数据在保存时不进行是否有可疑数据的判断
     */
    MANUAL(9, "人工数据");

    @EnumValue
    private int index;
    private String name;

    @Override
    public String toString() {
        if (this != null)
            return this.name;

        return null;
    }

    /**
     * 根据int型数值获取对应的枚举
     *
     * @param index int型数值
     * @return qc.common.core.enums.qms.QmsPointDataQualityEnum
     * @author QuCheng Tech
     * @since 2025/10/2
     */
    public static QmsPointDataQualityEnum getQmsPointDataQualityEnum(Integer index) {
        if (index != null && index > 0x0) {
            for (QmsPointDataQualityEnum item : QmsPointDataQualityEnum.values()) {
                if (item.getIndex() == index) {//判断序号使用getIndex，判断内容使用getName
                    return item;
                }
            }
        }
        return QmsPointDataQualityEnum.UN_DEFINE;
    }

    /**
     * 根据已有数据质量标记和当前数据质量判断判断是否要更新数据
     *
     * @param quality      本次拟更新数据质量标记
     * @param existQuality 已有数据质量标记
     * @return boolean
     * @author QuCheng Tech
     * @since 2025/9/29
     */
    public static boolean judgeNeedUpdateData(QmsPointDataQualityEnum quality, QmsPointDataQualityEnum existQuality) {
        //数据质量为UN_DEFINE当做null处理
        if (existQuality == null || existQuality == UN_DEFINE) {
            //如果已有和当前数据质量均为null；需要更新数据
            //如果已有数据质量为null，当前数据质量不为null；需要更新数据
            return true;
        } else {
            //已有数据质量不为null或UN_DEFINE
            if (quality == null || quality == UN_DEFINE) {
                //当前数据质量为null；无法确定当前数据质量是否符合，当做无效数据，不需要更新数据
                return false;
            } else if (quality == DELETE || quality == ERROR) {
                //当前数据质量为人工操作结果：删除或标记为错误
                if (quality == existQuality) {
                    //如果已有的数据已经是删除或错误数据，不需要重复操作
                    return false;
                }
                //其他情况均需要更新数据；如已有为删除，本次为标记为错误数据；已有为错误数据，本次为删除；
                return true;
            } else if (quality == TEST || quality == QUESTION || quality == FILLING || quality == NORMAL) {
                //当前数据质量为系统自动结果：测试数据、可疑数据、插补数据、正常数据
                if (existQuality == MANUAL) {
                    //已有数据是人工数据，本次数据为系统自动数据；系统自动数据不覆盖人工数据
                    return false;
                } else if (existQuality == DELETE || existQuality == ERROR) {
                    //已有数据已经删除或标记为错误，使用系统自动数据进行覆盖
                    return true;
                } else if (quality.index < existQuality.index) {
                    //已有数据也是系统自动数据，判断数据质量级别大小；如已有数据是正常数据的只能用正常数据进行覆盖；
                    //已有数据质量级别＞本次数据质量级别，不覆盖已有数据
                    return false;
                }
                //其他情况均需要更新数据；
                return true;
            } else if (quality == MANUAL) {
                //本次是人工数据，均需要进行覆盖
                return true;
            }
        }

        return false;
    }
}
